package com.br4mmie.asciistory.battle;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;

import com.br4mmie.asciistory.ASCIIStoryActivity;
import com.br4mmie.asciistory.Animation;
import com.br4mmie.asciistory.FileGetter;

/**
 * 
 * @author Niels
 * EncounterAction class
 * describes all actions taken by both enemies and players
 */
public class EncounterAction {
	
	String name; //Actions' displayed name
	String actionText; //Actions text, to be displayed in the battle console
	Animation animation; // the battle animation
	int baseDamage; // the base damage
	int damageDice;// the number of rolls to determine damage
	int damageSidesPerDice; // the maximum value per damage roll
	int heal; // the heal value of this ability
	@SuppressWarnings("unused")
	private Enemy targetedEnemy; //the targeted enemy, used by encounter player
	
	private boolean targetsEnemy; //Booleans used to determine targeting
	private boolean targetsAll;
	private boolean targetsSelf;
	private boolean targetsAllies;
	
	/**
	 * Constructor, loads the action from the given file
	 * @param actfile file to load from
	 */
	public EncounterAction(String actfile) {
		loadFromFile(actfile);
		targetedEnemy = null;
	}
	/**
	 * Load function, loads the action from the given file
	 * @param filename File to load
	 */
	public void loadFromFile(String filename){
		BufferedReader in;
		try {
			in = new BufferedReader(new FileReader(FileGetter.getFilename(filename)));
			name = in.readLine();
			actionText = in.readLine();
			baseDamage = Integer.parseInt(in.readLine());
			damageDice = Integer.parseInt(in.readLine());
			damageSidesPerDice =Integer.parseInt(in.readLine());
			heal = Integer.parseInt(in.readLine());
			animation = new Animation(in.readLine(), 1, 1);
			String line = in.readLine();
			targetsEnemy = line.toUpperCase().contains("ENEMY");
			targetsAll = line.toUpperCase().contains("ALL");
			targetsSelf = line.toUpperCase().contains("SELF");
			targetsAllies = line.toUpperCase().contains("ALLIES");
			in.close();
			
		} 
		catch(FileNotFoundException e)
		{
			System.out.println("File not found " + filename);
		}
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		
	}
	/**
	 * The Act function, called when the action is selected
	 * @param b Battle this action is used in
	 * @param caster The casting creature
	 */
	public void act(Battle b, EncounterCreature caster)
	{
		ArrayList<Enemy> enemies = b.getEnemies();
		EncounterPlayer player = b.getPlayer();
		/*
		 *Handles being cast by a player, requests a target from the player 
		 */
		if(caster instanceof EncounterPlayer)
		{
			if(targetsEnemy)
			{
				if(targetsAll)
				{
					b.addMessage(caster.getName() + actionText);
					for(Enemy e : enemies)
					{
						e.takeDamage(calcDamage(caster), b);
					}
					animation.setLocX((ASCIIStoryActivity.getScreenWidth()/2)-(animation.getWidth()/2));
					animation.setLocY((ASCIIStoryActivity.getScreenHeight()/2)-(animation.getHeight()/2));
				}
				else
				{
					EncounterCreature target = player.requestTarget(this);
					b.addMessage(caster.getName() + actionText + " Target: " + target.getName());
					target.takeDamage(calcDamage(caster), b);
					Enemy t = (Enemy) target;
					animation.setLocX(t.getScreenPosX());
					animation.setLocY(t.getScreenPosY());
				}
			}
			if(targetsSelf)
			{
				b.addMessage(caster.getName() + actionText);
				player.takeDamage(0-heal, b);
				animation.setLocX((ASCIIStoryActivity.getScreenWidth()/2)-(animation.getWidth()/2));
				animation.setLocY((ASCIIStoryActivity.getScreenHeight()/2)-(animation.getHeight()/2));
			}
		}
		/*
		 *Handles being cast by an Enemy
		 */
		else
		{
			if(targetsAllies && (enemies.size() > 1))
			{
				if(targetsAll)
				{
					b.addMessage(caster.getName() + actionText);
					for(Enemy e: enemies)
					{
						if(e != caster)e.takeDamage(0-heal, b);
					}
				}
				else
				{
					Enemy target = enemies.get(0);
					if(target == caster)target = enemies.get(1);
					for(Enemy e : enemies)
					{
						if(e != caster)
						{
							if((e.getCurrentHP()/e.getMaxHP())<=(target.getCurrentHP()/target.getMaxHP()))target = e;
						}
					}
					b.addMessage(caster.getName() + actionText + " Target:" + target.getName());
					target.takeDamage(0-heal, b );
				}
			}
			if(targetsEnemy)
			{
				b.addMessage(caster.getName() + actionText);
				player.takeDamage(calcDamage(caster), b);
			}
			if(targetsSelf)
			{
				b.addMessage(caster.getName() + actionText);
				caster.takeDamage(0-heal, b);
			} 
		}
		if(caster instanceof Enemy)
		{
			animation.setLocX(((Enemy) caster).getScreenPosX());
			animation.setLocY(((Enemy) caster).getScreenPosY());
		}
		
		animation.play(1);
		b.setAnimation(animation);
	}
	/**
	 * CalcDamage calculates the damage dealt by this action
	 * @param caster The creature invoking the action
	 * @return Returns the damage dealt by this ability
	 */
	private int calcDamage(EncounterCreature caster)
	{
		int damage = baseDamage+caster.getBonusDamage();
		for(int i = 0; i < damageDice; i++)
		{
			damage += (int)((Math.random()*damageSidesPerDice)+1);
		}
		return damage;
	}
	
	public void setTargetedEnemy(Enemy e)
	{
		targetedEnemy = e;
	}
}
